﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WordNet.Core;
using WordNet.Core.DataContract;
using WordNet.Core.ElementContracts;

namespace DataFileProvider
{
    public class SynsetMapper: IDataMapper<ISynset>
    {
        IDataProvider<ISynset> _fpSynset;
        public SynsetMapper(IDataProvider<ISynset> provider)
        {
            _fpSynset = provider;
        }
        
        public IEnumerable<ISynset> GetAll(POS pos)
        {
            if (pos == null)
                throw new ArgumentException();
            
            if (!_fpSynset.IsOpen) _fpSynset.Open();

            var content = ContentType<ISynset>.GetDataContentType(pos);
            var parser = content.DataType.GetParser();
            IDataSource file = _fpSynset.GetSourceForContentType(content);

            foreach (var synseLine in file.AllLines())
            {
                var synset = parser.Parse(synseLine);
                setHeadWord(synset);
                yield return synset;
            }
        }

        public ISynset GetByKey(object key)
        {
            if (key == null || !(key is ISynsetID))
                throw new ArgumentException();
            ISynsetID id = (ISynsetID)key;
            if (!_fpSynset.IsOpen) _fpSynset.Open();
            var content = ContentType<ISynset>.GetDataContentType(id.PartOfSpeech);
            IDataSource file = _fpSynset.GetSourceForContentType(content);
            //String offset = Synset.ZeroFillOffset(id.GetOffset());

            String line = file.ReadLine(id.Offset);

            if (line == null)
                throw new ArgumentException();
            ISynset synset = content.DataType.GetParser().Parse(line);
            setHeadWord(synset);
            return synset;
        } 

        public ISynset GetDefinition(string query)
        {
            throw new NotImplementedException();
        }

        protected void setHeadWord(ISynset synset)
        {
            if (synset == null) return;
            // head words are only needed for adjective satellites
            if (!synset.IsAdjectiveSatellite) return;

            // go find the head word
            ISynset headSynset;
            IWord headWord = null;
            foreach (ISynsetID simID in synset.GetRelatedSynsets(Pointer.SIMILAR_TO))
            {
                headSynset = GetByKey(simID);
                // assume first 'similar' adjective head is the right one
                if (headSynset.IsAdjectiveHead)
                {
                    headWord = headSynset.GetWords()[0];
                    break;
                }
            }
            if (headWord == null) return;

            // set head word, if we found it
            String headLemma = headWord.Lemma;

            // version 1.6 of Wordnet adds the adjective marker symbol 
            // on the end of the head word lemma
            // IVersion ver = getVersion();
            //  boolean isVer16 = (ver == null) ? false :  ver.getMajorVersion() == 1 && ver.getMinorVersion() == 6;
            // if(isVer16 && headWord.getAdjectiveMarker() != null) headLemma += headWord.getAdjectiveMarker().getSymbol(); 

            // set the head word for each word
            foreach (IWord word in synset.GetWords())
            {
                if (word.SenseKey.NeedsHeadSet) word.SenseKey.SetHead(headLemma, headWord.LexicalID);
            }


        }
        public IDataProvider<ISynset> DataProvider
        {
            get { return _fpSynset; }
        }
    }
}
